/**
 * All Rights Reserved , Copyright (C) 2020 , 青岛鼎信通讯股份有限公司
 * <p>
 * MpmProjectController
 * 项目立项
 * <p>
 * 修改纪录
 * 2020-12-25 版本：1.0 lanjianwei 创建。
 *
 * @version 版本：1.0
 * @author 作者：lanjianwei
 * 创建日期：2020-12-25
 */

package com.topscomm.mpm.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.topscomm.basic.exception.BusinessException;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.*;
import com.topscomm.cbo.service.ICboExcelExportTaskService;
import com.topscomm.cbo.service.ICboItemDetailsService;
import com.topscomm.cbo.service.ICboItemsService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.controller.auto.MpmProjectControllerAuto;
import com.topscomm.mpm.pojo.MpmProjectAppointmentEntity;
import com.topscomm.mpm.pojo.MpmProjectEntity;
import com.topscomm.mpm.pojo.MpmProjectPlanEntity;
import com.topscomm.mpm.pojo.MpmProjectTaskEntity;
import com.topscomm.mpm.service.*;
import com.topscomm.pub.util.*;
import com.topscomm.pub.vo.Page;
import com.topscomm.pub.vo.Query;
import com.topscomm.pub.vo.ResponseResult;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.ParameterCache;
import com.topscomm.tap.common.SessionUserBean;
import com.topscomm.tap.constant.TapHttpErrorCode;
import com.topscomm.tap.constant.TapHttpStatus;
import com.topscomm.tap.threadlocal.ThreadLocalContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @description: 系统首页接口
 * @return:
 * @date: 2021/1/7 17:29
 */
@RestController
@RequestMapping("mpm/mpmIndex")
public class MpmIndexController extends MpmProjectControllerAuto {
    @Autowired
    private IMpmProjectMilepostService mpmProjectMilepostService;
    @Autowired
    private IMpmProjectService mpmProjectService;
    @Autowired
    private IMpmProjectTaskService mpmProjectTaskService;
    @Autowired
    private DatacodeCache datacodeCache;
    @Autowired
    private IMpmDataBoardCustomizeRecordService mpmDataBoardCustomizeRecordService;
    @Autowired
    private IMpmWorkingCalendarService mpmWorkingCalendarService;
    @Autowired
    private ICboItemsService iCboItemsService;
    @Autowired
    private ICboItemDetailsService iCboItemDetailsService;

    /**
     * @description: 超期项目和里程碑及任务
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/7 17:36
     */
    @GetMapping("/queryOverdueInfo")
    public ResponseResult<Object> queryOverdueInfo(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            List<Map<String, Object>> resultMapList = mpmProjectService.queryOverdueInfo(paraMap);
            return ResponseResult.ok(resultMapList);
        } catch(Exception e) {
            return ResponseResult.error("请求首页信息概览内容出错，请联系管理员!");
        }

    }

    /**
     * @description: 即将超期任务查询接口
     * @param: paraMap (必传过期天数（overdueDays）)
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/8 11:16
     */
    @GetMapping("/querySoonOverdueTask")
    public ResponseResult<Object> querySoonOverdueTask(@RequestParam(required = false) Map<String, Object> paraMap) {
        //========================================== 三天/一周内过期的任务（即当前未超期，三天/一周后超期的任务）=======================
        try {
            List<Map<String, Object>> soonOverdueTaskList = mpmProjectService.querySoonOverdueTask(paraMap);
            return ResponseResult.ok(soonOverdueTaskList);
        } catch (Exception e) {
            return ResponseResult.error("请求首页超期任务内容出错，请联系管理员!");
        }
    }

    /**
     * 导出大数据量的excel
     *
     * @description:
     * @param paraMap
     * @param request
     * @param response
     * @author: heyiheng
     * @date: 2023年3月27日下午2:11:14
     * @modify:
     */
    @PostMapping(value = "/exportBigExcel")
    public ResponseResult<Object> exportBigExcel(@RequestBody(required = false) Map<String, Object> paraMap,
                                                 HttpServletRequest request, HttpServletResponse response) {
        //导出参数设定
        String cols = ConvertUtil.convertToString(paraMap.get("cols"));
        String fileName = ConvertUtil.convertToString(paraMap.get("fileName"));
        fileName = fileName.length() == 0 ? "导出数据.xlsx" : fileName + ".xlsx";
        try {
            //获得导出数据，一次导出所有页面的数据
            paraMap.put("pageSize", "10000");
            paraMap.put("overdueDays","7");
            paraMap.put("sidx", "PLANENDDATE");
            paraMap.put("dataPermissionFlag", "org");
            List<Map<String, Object>> taskList = mpmProjectService.querySoonOverdueTask(paraMap);
            // 导出数据
            exportExcelXlsx(response, taskList, fileName, cols);
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
    /**
     * 导出excel
     *
     * @description:
     * @param fileName
     * @param columns
     * @return
     * @author: heyiheng
     * @date: 2023年3月27日下午14:52:17
     * @modify:
     */
    @SuppressWarnings("rawtypes")
    private void exportExcelXlsx(HttpServletResponse response, List<Map<String, Object>> responseList, String fileName,
                                 String columns) throws Exception {
        // 在导出数据中加上超期类型字段
        DateTime dateTime = DateUtil.offsetDay(new Date(),3);// 获取3天后的时间
        // 任务结束时间在三天内的赋值三天内，其余为一周内
        for(Map map : responseList) {
            Date planEndDate = (Date) map.get("planenddate");
            if(dateTime.isBefore(planEndDate)) {
                map.put("datetype","一周内");
            } else {
                map.put("datetype", "三天内");
            }
        }
        InputStream inputStream = null;
        try {
            int len;
            inputStream = OfficeOperateUtil.exportExeclXlsx(responseList, columns.split(","));
            if (inputStream != null) {
                response.setContentType("application/vnd.ms-excel");
                response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                response.setHeader("istaskexport", "0");
                response.setHeader("Access-Control-Expose-Headers", "istaskexport");
                response.setHeader("FileName", URLEncoder.encode(fileName, "utf-8"));
                response.setHeader("Access-Control-Expose-Headers", "FileName");
                OutputStream outStream = response.getOutputStream();
                byte[] bytes = new byte[2048];
                while ((len = inputStream.read(bytes)) != -1) {
                    outStream.write(bytes, 0, len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @description: 查询近期创建或者近期完成的项目（一个月内）
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/9 15:39
     */
    @GetMapping("/queryRecentlyCreateOrComplete")
    public ResponseResult<Object> queryRecentlyCreateOrComplete(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            List<Map<String, Object>> result = mpmProjectService.queryRecentlyCreateOrComplete(paraMap);
            return ResponseResult.ok(result);
        } catch(Exception e) {
            return ResponseResult.error("请求首页项目信息内容出错，请联系管理员!");
        }
    }

    /**
     * @description: 首页echarts数据
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/11 9:28
     */
    @GetMapping("/getIndexEhartsInfo")
    public ResponseResult<Object> queryProjectLevelSatistics(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            Map<String, Object> result = mpmProjectService.queryProjectLevelSatistics(paraMap);
            return ResponseResult.ok(result);
        }  catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 获取数据看板中各个位置的组件信息
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/11 11:02
     */
    @GetMapping("/getComponentsList")
    public ResponseResult<Object> getComponentsList(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            List<Map<String, Object>> componentsList = mpmProjectService.getComponentsList(paraMap);
            return ResponseResult.ok(componentsList);
        } catch(Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 获取数据中心组件数据(整个系统中的数据统计)
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/11 15:27
     */
    @GetMapping("/getDataCenterInfo")
    public ResponseResult<Object> getDataCenterInfo(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            Map<String, Object> result = mpmProjectService.getDataCenterInfo(paraMap);
            return ResponseResult.ok(result);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 获取金额Top10
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/13 8:38
     */
    @GetMapping("/getMoneyTop10")
    public ResponseResult<Object> getMoneyTop10(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle(" state = 9 and {0}", mpmProjectService.spellSqlForDataBoard(paraMap, MpmProjectEntity.tableName, MpmProjectEntity.FieldProjectcode));
            List<Map<String, Object>> list = mpmProjectService.queryMapByWhere(sql.toString(), "projectMoneyTop10");
            return ResponseResult.ok(list);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 获取项目数量Top10
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/13 10:24
     */
    @GetMapping("/getProjectCountTop10")
    public ResponseResult<Object> getProjectCountTop10(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle(" state = 9 and {0}", mpmProjectService.spellSqlForDataBoard(paraMap, MpmProjectEntity.tableName, MpmProjectEntity.FieldProjectcode));
            List<Map<String, Object>> list = mpmProjectService.queryMapByWhere(sql.toString(), "projectCountTop10");
            return ResponseResult.ok(list);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 查询各个省区的项目级别数量情况
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/9/8 刘晨光 修改为简称
     */
    @GetMapping("/queryProvincesProjectLevelsCountInfo")
    public ResponseResult<Object> queryProvincesProjectLevelsInfo(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            Map<String, Object> result = mpmProjectService.queryProvincesProjectLevelsInfo(paraMap);
            return ResponseResult.ok(result);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 数据看板上项目级别饼图信息
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/11 9:28
     */
    @GetMapping("/getDataBoardProjectLevelEhartInfo")
    public ResponseResult<Object> getDataBoardProjectLevelEhartInfo(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            List<Map<String, Object>> listForLevel = mpmProjectService.getDataBoardProjectLevelEhartInfo(paraMap);
            return ResponseResult.ok(listForLevel);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 查询项目列表
     * @param: paraMap
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/13 11:14
     */
    @GetMapping("/list")
    public ResponseResult<Object> list(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            Page page = mpmProjectService.listForMpmIndexController(paraMap);
            return ResponseResult.ok(page);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * 获取综合项目信息
     * @author: houyuhang
     * @date: 2021-12-01
     * @return ResponseResult<Object>
     */
    @GetMapping("/overallProjectInfo")
    public ResponseResult<Object> overallProjectInfo(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            List<Map<String, Object>> echartsDataForProjectStateForMobile = mpmProjectService.overallProjectInfo(paraMap);
            return ResponseResult.ok(echartsDataForProjectStateForMobile);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }
    /**
     * @author: houyuhang
     * @date: 2021-12-01
     * @description: 获取首页是否有“公司数据”的权限
     * @return: AtomicBoolean
     */
    @GetMapping("/getIndexPermission")
    public ResponseResult<Object> getIndexPermission(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            AtomicBoolean hasOrg = mpmProjectService.getIndexPermission(paraMap);
            return ResponseResult.ok(hasOrg.get());
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * @description: 从线程本地副本中获取用户信息
     * @param:
     * @return: com.topscomm.tap.common.SessionUserBean
     * @author Administrator
     * @date: 2021/1/7 19:18
     */
    public SessionUserBean getUserBean() {
        return (SessionUserBean) ThreadLocalContext.sessionUserBeanThreadLocal.get();
    }

    /**
     * @author: houyuhang
     * @date: 2023-01-04
     * @description: 获取deptcommoncode的编码
     */
    @GetMapping("/queryCodeList")
    public ResponseResult<Object> queryCodeList(@RequestParam(required = false) Map<String, Object> paraMap) {
        try {
            Map<String, Object> codeMap = new HashMap<String, Object>();
            // 部门名称编码，由于redis未存储sortcode，为了防止deptcommoncode顺序混乱,从数据库中查询deptcommoncode
            List<Map<String, Object>> deptcommoncode1List = new ArrayList<Map<String, Object>>();
            CboItemsEntity deptItemsEntity = iCboItemsService.queryObjectByWhere("code = 'DeptCommonCodeTrack'");
            List<CboItemDetailsEntity> deptCommonCodes = iCboItemDetailsService.queryByWhere("itemid=" + deptItemsEntity.getId() + " and enabled=1 order by sortcode asc");
            for (CboItemDetailsEntity codeItem : deptCommonCodes) {
                Map<String, Object> addItem = new HashMap<>();
                addItem.put("id", codeItem.getId());
                addItem.put("code", codeItem.getCode());
                addItem.put("name", codeItem.getName());
                deptcommoncode1List.add(addItem);
            }
            codeMap.put("deptCommonCodeList", deptcommoncode1List);
            return ResponseResult.ok(codeMap);
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }
}
